using System;
using System.Collections.Generic;
namespace xmldict{
	class Utils {
		private Utils(){}
		private static readonly Type t_IMinimalDict= typeof(IMinimalDict);
		private static readonly Type t_IMinimalList= typeof(IMinimalList);
		private static readonly Type t_Dict = typeof(IDictionary<string, object>);
		private static readonly Type t_List = typeof(IList<object>);

		public static bool InstanceOf(object obj, Type type){
			if(obj == null || type == null){
				return false;
			}
			Type t = obj.GetType();
			return t.Equals(type) 
				|| t.IsSubclassOf(type) 
				|| type.IsAssignableFrom(t);
		}
		public static bool isDict(object data){
			return InstanceOf(data, t_IMinimalDict) || InstanceOf(data, t_Dict);
		}

		public static IMinimalDict asDict(object data){
			if(InstanceOf(data, t_IMinimalDict)){
				return (IMinimalDict)data;
			}
			if (InstanceOf(data, t_Dict)){
				return new DictAdapter((IDictionary<string, object>)data);
			}
			return null;
		}

		public static bool isList(object data){
			return InstanceOf(data, t_IMinimalList) ||InstanceOf(data, t_List);
		}
		
		public static IMinimalList asList(object data){
			if (InstanceOf(data, t_IMinimalList)){
				return  data as IMinimalList;
			}
			if (InstanceOf(data, t_List)){
				return new ListAdapter((IList<object>)data);
			}
			return null; 
		}
		
		public static IMinimalDict getDict(IMinimalDict dict, params string[] keys){
			if (keys.Length == 0) {
				return null;
			}
			IMinimalDict curr = dict;
			for (int i=0;i<keys.Length; i++){
				string key = keys[i];
				object data = curr[key];
				if (data == null){
					throw new NullReferenceException("no data found for key: "+ key);
				}
				curr = asDict(data);
				if(curr == null){
					throw new InvalidCastException("Data is not dict for key: "+ key);
				}				
			}
			return curr;
		}
	}	
}
